package com.oocl.server.impl;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.oocl.qq.protocol.Action;
import com.oocl.qq.protocol.Protocol;
import com.oocl.server.Server;
import com.oocl.server.dao.UserDao;
import com.oocl.server.dao.impl.UserDaoImpl;
import com.oocl.server.pojo.User;
import com.oocl.server.runnable.ChatRunnable;
import com.oocl.server.util.Logger;

/**
 * Server :  仅仅作为一个封装和服务
 * 启动
 * 关闭
 * @author WUJA13
 *
 */
public class ChatServer implements Server{

//	private static  ChatServer sInstance;
	private ServerSocket serverSocket;
	
	private  Map<String ,ChatRunnable> threadMap = null;
	
	private ExecutorService singleService = Executors.newSingleThreadExecutor();

	private boolean isOpened = false;
	
	@Override
	public void start(){
		this.isOpened = true;
		singleService.submit(new Runnable() {
			
			@Override
			public void run() {
				try{
					if(serverSocket==null || serverSocket.isClosed()){
						serverSocket = new ServerSocket(8001);
						threadMap = new ConcurrentHashMap<String,ChatRunnable>();
					}
					Logger.log("IM服务端启动");
					while(isOpened && serverSocket!=null && !serverSocket.isClosed()){
						Socket socket = serverSocket.accept();
						Logger.log("8001端口有Client连接上");
						ChatRunnable thread = new ChatRunnable(socket, threadMap);
						thread.start();
					}
										
					}catch(IOException e){
						e.printStackTrace();
					}finally{
						///这里，表示所有Client都需要被关闭
						///关闭之前，做个处理
						doBeforeClose();
					}
			}

			
		});
	}
	
	private void doBeforeClose() {
	//	System.out.println("doBeforeClose()");
		UserDao userDao = new UserDaoImpl();
		
		Set<String> onlineUserSet = threadMap.keySet();
		for(String name: onlineUserSet){
			threadMap.get(name).sendMsg(new Protocol(Action.Logout, null));
		}
		
		List<User> userList = userDao.findAll();
		if(userList!=null && userList.size()>0){
			for(User user: userList){
				
				user.setOnline(false);
				userDao.updateUser(user);
			}
		}
		threadMap.clear();
	}
	
	@Override
	public void stop() {
	//	System.out.println("stop ....");
		if(this.serverSocket.isClosed())
			return;
		try {
			this.isOpened = false;
			this.serverSocket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			doBeforeClose();
		}
	}
	
	@Override
	public boolean isClosed() {
		return (this.isOpened == false ||this.serverSocket==null||this.serverSocket.isClosed());
	}

}
